
/**  
* @Title: DbCacheAop.java
* @Package com.wq.aop
* @Description: 
* @author likai
* @date 2017年5月18日
* @version V1.0  
*/

package com.frames.datasource;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.supers.annotation.CacheHandle;
import com.supers.enums.SqlType;
import com.utils.md5.EncryptUtil;
import com.utils.transtype.JsonObjectUtil;

/**
 * @ClassName: DbCacheAop
 * @Description:数据库缓存策略拦截处理(mybatis使用)
 * @author likai
 * @date 2017年5月18日
 *
 */
public class DbCacheAop{
	public static Logger log = LoggerFactory.getLogger(DbCacheAop.class);
	@Resource
	private SqlSessionFactory sqlSessionFactory;
	

	@SuppressWarnings({ "unused", "rawtypes" })
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		Object retVal = null;		
		Signature s = pjp.getSignature();//获取切面对象
		MethodSignature ms = (MethodSignature) s;
		Method m = ms.getMethod();
		CacheHandle cacheHandle = m.getAnnotation(CacheHandle.class);
		if (cacheHandle!=null) {
			//使用了缓存处理
			if (cacheHandle.handle().equals(SqlType.QUERY)) {
				//---------------查询数据缓存处理----------
				StringBuffer paramStr=new StringBuffer();
				Object[] args = pjp.getArgs();
				//1.获取查询sql
				Map<String, Object> map=new HashMap<String, Object>();
				Parameter[] parameters=m.getParameters();//获取方法参数列表
				for (int i = 0; i < parameters.length; i++) {
					Parameter parameter=parameters[i];
					String paramName="";
					Param paramAnn=parameter.getAnnotation(Param.class);
					if (paramAnn!=null) {
						//使用mybatis参数注解，获取注解的参数名
						paramName=paramAnn.value();
					}else {
						//未使用mybatis参数注解，获取方法的参数名
						if (parameter.isNamePresent()) {
							paramName=parameter.getName();
						}else {
							new RuntimeException("不能获取方法的参数名，请启用jdk8环境-parameters参数对项目进行编译");
						}
					}
					Object arg=args[i];
					if (arg!=null) {			
						if (arg instanceof Object[]) {
							arg=Arrays.toString((Object[]) arg);
						}
						paramStr.append(JsonObjectUtil.NON_DEFAULT.objectToJson(arg));
					}
					map.put(paramName, arg);
				}							
				
				String target=s.getDeclaringTypeName()+"."+s.getName();
				String sql=sqlSessionFactory.getConfiguration().getMappedStatement(target).getBoundSql(map).getSql();
				//获取缓存的键
				String cacheKey=EncryptUtil.encodedByMD5(sql+paramStr);
				log.info("sql----------------"+sql);
				log.info("cacheKey----------------"+cacheKey);
				if (false) {
					//有缓存，则返回缓存数据
				}else {
					//无缓存，添加缓存，并返回数据
				}
			}else {
				//--------------修改数据缓存处理--------------
				//1.获取表名
				Class c=Class.forName(s.getDeclaringTypeName());
				String tableName=c.getDeclaredField("table").get(c).toString();//获取对象属指定性值
				//2.删除对应表的缓存
			}
		}
		return pjp.proceed();
	}


	public SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}


	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}
	
	
	
}
